home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / diskutil / noahdi.zoo / noahdi / hd_med.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  9KB  |  280 lines

  1. /*
  2.     File: HD_MED.C       Medium Level Harddisk Driver. AHDI Compatible.
  3. */
  4. /*
  5. Copyright (c) 1988 - 1991 by Ted Schipper.
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation.
  12.  
  13. This software is provided AS IS with no warranties of any kind.  The author
  14. shall have no liability with respect to the infringement of copyrights,
  15. trade secrets or any patents by this file or any part thereof.  In no
  16. event will the author be liable for any lost revenue or profits or
  17. other special, indirect and consequential damages.
  18. */
  19.  
  20. #include "bios.h"
  21. #include "hddriver.h"
  22. #include "system.h"
  23.  
  24. /***************************************************************************
  25.  
  26.                             MEDIUM-LEVEL Driver
  27.                            ---------------------
  28.  HISTORY
  29. ---------
  30.  Feb 1989. THS. Started. Tested read/write routines.
  31.                 V0.00
  32.  
  33. ***************************************************************************/
  34.  
  35. /***************************************************************************
  36.  
  37.                           Global Variables
  38.  
  39. ***************************************************************************/
  40.  
  41. /* Initialize variables to get them into the driver code */
  42.  
  43. struct bpb bpbs[MAX_UNITS] = {0,0};        /* BPB Block for each device */
  44. struct hd_drv pun[MAX_UNITS] = {0,0};      /* PUN table for each device */
  45.   
  46. /***************************************************************************
  47.  *
  48.  * Function name : sasi_init. Initialize SASI device.
  49.  * Parameters    : none.
  50.  * Returns       : long OK    = initialize went OK
  51.  *                      ERROR = initialize error or no drive present
  52.  * Description   : Initialize a ASCI (SCSI) controller.
  53.  * Comments      : Not used. Only needed for controllers who's parameters
  54.  *                 must be set.
  55.  */
  56.  
  57. long sasi_init()
  58. {
  59.  return(OK);
  60. }
  61.  
  62.  
  63. /***************************************************************************
  64.  *
  65.  * Function name : sasi_bpb. Return pointer to device BPB.
  66.  * Parameters    : short device. Logical device number.
  67.  * Returns       : long. Pointer to device BPB.
  68.  * Description   : Return the pointer to requested device's BPB.
  69.  * Comments      : 
  70.  */
  71.  
  72. long sasi_bpb(dev)
  73.  
  74. short dev;
  75.  
  76. {
  77.  return((long) &bpbs[dev]);  /* addr of first struct element */
  78. }
  79.  
  80.  
  81. /***************************************************************************
  82.  *
  83.  * Function name : ahdi_rw. Read/write harddisk device sectors
  84.  * Parameters    : short rwflags. Read/write flags:
  85.  *                                bit 0: 0 = read, 1 = write
  86.  *                                bit 1: media change. not used yet.
  87.  *                                bit 2: 0 = with retries, 1 = no retries
  88.  *                                bit 3: 0 = logical, 1 = physical operation
  89.  *                 long  buffer.  Address of buffer.
  90.  *                 short count.   Number of sectors to read/write.
  91.  *                 short recno.   Start sector number.
  92.  *                 short device.  Logical device number.
  93.  * Returns       : long. OK      = read/write wend well
  94.  *                       EREADF  = read error
  95.  *                       EWRITEF = write error
  96.  * Description   : Read/write sectors from/to a harddisk. If more than
  97.  *                 254 sectors are requested, do multiple 254 sector
  98.  *                 tranfers. If buffer is on an odd address, use the BIOS
  99.  *                 2 sector buffer for the transfer.
  100.  * Comments      : 
  101.  */
  102.  
  103. long sasi_rw(flags,buf,count,recno,dev)
  104.  
  105.  short flags;
  106.  long  buf;
  107.  short count;
  108.  short recno;
  109.  short dev;
  110.  
  111. {
  112.  short sec_cnt;
  113.  long  buf_ptr;
  114.  long  status;
  115.  
  116.  do
  117.  {
  118.     if (count == 0)       /* is there anything to be done */
  119.        return(OK);        /* no, so done with no errors */
  120.  
  121.     sec_cnt = count;
  122.     buf_ptr = buf;
  123.  
  124.     if (count > MAXSECTORS) /* more than one DMA full */
  125.        sec_cnt = MAXSECTORS; /* yes, so only do this many this time */
  126.  
  127.     if (buf & 0x0001)        /* buffer at an odd boundry */
  128.     {
  129.        if (count > 2)        /* more than 2 sectors */
  130.           sec_cnt = 2;       /* set sector to size of BIOS buffer */
  131.        buf_ptr = DSKBUFP;    /* use BIOS buffer for this transfer */
  132.  
  133.        if (flags & RW_FLAG)  /* is this a write */
  134.           smove(buf_ptr,buf,sec_cnt); /* copy sectors to BIOS buffer */
  135.     }
  136.  
  137.     if ((status = do_rw(flags,buf_ptr,sec_cnt,recno,dev)) != OK) /* read/write went wrong */
  138.        return(status);                   /* yes, so give up */
  139.  
  140.     if (buf & 0x0001)        /* buffer at an odd boundry */
  141.     {
  142.        if ((flags & RW_FLAG) == 0) /* and a read */
  143.           smove(buf,buf_ptr,sec_cnt); /* copy sectors to destination */
  144.     }
  145.  
  146.     buf += (long)((long)sec_cnt * 512L);  /* ajust buffer start */
  147.     recno += sec_cnt;        /* ajust start sector */
  148.     count -= sec_cnt;        /* ajust sectors to be done */
  149.  } while (count > 0);        /* do again if sectors left */
  150.  return(OK);                 /* all done with no errors */
  151. }
  152.  
  153.  
  154. /***************************************************************************
  155.  *
  156.  * Function name : smove. Copy sectors arround in memory.
  157.  * Parameters    : char *dest. Pointer to destination address.
  158.  *                 char *src.  Pointer to source address.
  159.  *                 short count. Number of sectors to copy.
  160.  * Returns       : none.
  161.  * Description   : Copy sectors from source to destination. Calculate the
  162.  *                 number of bytes to copy by multiplying by 512.
  163.  * Comments      : 
  164.  */
  165.  
  166. void smove(dest,src,count)
  167.  
  168.  char  *dest;
  169.  char  *src;
  170.  short count;
  171.  
  172. {
  173.   /* calculate bytes to be moved, 1024 tops */
  174.  
  175.  for (count *= 512; count > 0; count--) /* calc bytes to move, and do it */
  176.      *dest++ = *src++;                  /* copy a byte */
  177. }
  178.  
  179.  
  180. /***************************************************************************
  181.  *
  182.  * Function name : do_rw. Read/write no more than 254 sectors.
  183.  * Parameters    : short rwflags. Read/write flags:
  184.  *                                bit 0: 0 = read, 1 = write
  185.  *                                bit 1: media change. not used yet.
  186.  *                                bit 2: 0 = with retries, 1 = no retries
  187.  *                                bit 3: 0 = logical, 1 = physical operation
  188.  *                 long  buffer.  Address of buffer.
  189.  *                 short count.   Number of sectors to read/write.
  190.  *                 short recno.   Start sector number.
  191.  *                 short device.  Logical device number.
  192.  * Returns       : long. OK      = read/write wend well
  193.  *                       EREADF  = read error
  194.  *                       EWRITEF = write error
  195.  * Description   : Reda/write no more than 254 sectors with retries. If
  196.  *                 an error occurs, call the critical error handler.
  197.  * Comments      : 
  198.  */
  199.  
  200. long do_rw(flags,buf,count,recno,dev)
  201.  
  202.  short flags;
  203.  long  buf;
  204.  short count;
  205.  short recno;
  206.  short dev;
  207.  
  208. {
  209.  short retries;
  210.  short pdev;
  211.  long  status;
  212.  long  sec_no;
  213.  long  hz_200_sync;
  214.  func  evt_critic;
  215.  
  216.  do
  217.  {
  218.     retries = MAXRETRIES;            /* setup retry counter */
  219.     if (flags & RETRY_FLAG)          /* retries disabled ? */
  220.        retries = 0;                  /* yes, retry counter to zero */
  221.  
  222.     do
  223.     {                                /* first sync with 200 Hz timer. WHY ? */
  224.        hz_200_sync = HZ_200;         /* get 200 Hz ticker value */
  225.        while (hz_200_sync == HZ_200) ; /* wait for 1 tick to elapse */
  226.        hz_200_sync = HZ_200 + 1;     /* ajust variable to ticker + 1. WHY ? */
  227.  
  228.        if (flags & PHYSOP_FLAG)      /* physical unit operation */
  229.        {
  230.           pdev = dev - 2;   /* ??????? yes, do logical to physical mapping */
  231.           sec_no = (long) recno;
  232.        }
  233.        else                          /* logical operation */
  234.        {
  235.           pdev = pun[dev].dev_addr;  /* get partitions ASCI address */
  236.           sec_no = pun[dev].part_start + (long) recno; /* calc physical sector # */
  237.        }
  238.  
  239.        if (flags & RW_FLAG)          /* read or write ? */
  240.           status = hwrite(sec_no,count,buf,p